package com.nz.test.auto.core;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.Iterator;
import java.util.LinkedHashMap;

import com.nz.test.auto.inter.FuncContent;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;



/**
 * 根据用例路径和数据源路径 返回待执行列表
 */
public class ReadCase {
	
	MultiTools multiTools=new MultiTools();
	/**
	 * 返回待执行case的队列表,最初始的数据
	 * @param casePath
	 * @return
	 */
	private List<String> CaseInitList(String casePath) {
		DialectMap dialectMap = new DialectMap();
		WordStrcImp wordStrcImp = new WordStrcImp();
		String lineTxt = null;
		List<String> executeQueue = new ArrayList<>();
		File caseFile = new File(casePath);
		if (caseFile.isFile() && caseFile.exists()) {
			try {
				InputStreamReader read = new InputStreamReader(new FileInputStream(caseFile), "UTF-8");
				BufferedReader bufferedReader = new BufferedReader(read);
				

				try {
					String temp = null;// 缓冲字符串
					int Flag = 0;// 循环体标识
					while ((lineTxt = bufferedReader.readLine()) != null) {
						String or = wordStrcImp.getOrder(lineTxt);						
						if (lineTxt.length()!=0 && or != null) {
//							if(lineTxt.indexOf("循环") !=-1) {
//								Log.debug(or);
//							}
							int complex = dialectMap.getInstructionComplexity(or);// 复杂度
							if (Flag == 0) {
								if (complex == 1) {
									executeQueue.add(lineTxt);
								} else {
									temp = lineTxt;
									Flag = 1;
								}
							}else if(Flag==1) {
								String pattern="(\\s{2,}|\t)";
								Matcher matcher=Pattern.compile(pattern).matcher(lineTxt);
								if(matcher.find()) {
									lineTxt=lineTxt.replaceAll("\\s|\t", "");
									if(lineTxt!=null && lineTxt.length()!=0) {
										temp=temp+",("+lineTxt+")";
									}else {
										executeQueue.add(temp);
										temp=null;//回空
										Flag=0;
									}
								}else {
									executeQueue.add(temp);
									temp=null;//回空
									Flag=0;
									if (complex == 1) {
										executeQueue.add(lineTxt);
									} else {
										temp = lineTxt;
										Flag = 1;
									}
								}
							}
						}

					}
					if(temp!=null) {
						executeQueue.add(temp);
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			} catch (UnsupportedEncodingException | FileNotFoundException e) {
				e.printStackTrace();
			}

		}
		return executeQueue;
	}

	/**
	 *	提取用例中使用到的数据源变量
	 * @param casePath
	 * @return 
	 * @return
	 */
	private HashMap<String, String> DataSourceMap(String dataConf) {
		Config dataConfig=ConfigFactory.parseFile(new File(dataConf));
		HashMap<String, String> varMap=new HashMap<String,String>();
		Set<String> varsKeySet=dataConfig.root().keySet();
		Iterator<String> iterator=varsKeySet.iterator();
		while(iterator.hasNext()) {
			String key=iterator.next();
			String value=dataConfig.getString(key);
			varMap.put(key, value);
		}
		return varMap;
		
		
	}
	
	/**
	 *  case中的数据源var转换成实际数据
	 * @param 
	 * @return List<String> 数据源插入到用例表中
	 */
	public List<String> PreContentList(String casePath,String dataConf) {
		List<String> caseList=CaseInitList(casePath);
		HashMap<String,String> dataMap=this.DataSourceMap(dataConf);
		WordStrcImp wordStrcImp=new WordStrcImp();//词性分析器
		int cLength=caseList.size();
		for(int i=0;i<cLength;i++) {
			String content=caseList.get(i);
			List<String> vars=wordStrcImp.getVariable(content);
			for(String var:vars) {
				String varDetail=dataMap.get(var);
				if(varDetail!=null) {
					content=content.replaceAll("\\{"+var+"\\}", varDetail);
			}			
			caseList.set(i, content);
			}
		}
		return caseList;
	}
	/**
	 *  case中的指令转换成对应类
	 * @return 
	 * @return List<String> case中的指令转换成对应类
	 */
	public LinkedHashMap<String, FuncContent> ContentConvert(String casePath,String dataConf) {
		List<String> preList=PreContentList(casePath, dataConf);
		LinkedHashMap<String, FuncContent> map=new LinkedHashMap<String,FuncContent>();
		WordStrcImp wordStrcImp=new WordStrcImp();//词性分析器
		DialectMap dialectMap=new DialectMap();
		for(int i=0;i<preList.size();i++) {
			String content=preList.get(i);
			String or=wordStrcImp.getOrder(content);//方言指令
			String classNameKey=dialectMap.getClassName(or);
			Integer num=dialectMap.getParam(or);
			content=content.replaceAll("\\["+or+"\\]", "");
			List<String> contentList=Arrays.asList(content.split(",",num+1));
			List<String>  cList=new ArrayList<String>(contentList);
			FuncContent funcContent=new FuncContent();
			List<String> arguments=new ArrayList<String>();
			List<String> preToCaluse=new ArrayList<String>();
			for(int j=0;j<num;j++) {
				arguments.add(((String) cList.get(0)).replaceAll("\\(|\\)", ""));
				cList.remove(cList.get(0));//去除指令后的语句,列表化后个数多于参数个数,剩下数据列入子句
			}
			List<String> detailList=null;
			if(cList.size()>0) {
				//TODO: 判断括号成对匹配,嵌套 引入工具类MultiTools待完善
				detailList=multiTools.digMatchSubString(cList.get(0), 1);
				for(int j=0;j<detailList.size();j++) {
					detailList.set(j, detailList.get(j));
				}
			}		
			
			preToCaluse=detailList;
			funcContent.setArguments(arguments);
			funcContent.setPreToCaluse(preToCaluse);
			map.put(classNameKey, funcContent);			
		}
		return map;		
	}
	
	
	
	public static void main(String[] args) {
		ReadCase readCase=new ReadCase();
//		List<String> result=readCase.CaseInitList("case/demo/first.case");
//		Log.debug(result);
//		Log.debug(result.size());
//		
//		Log.debug(readCase.DataSourceMap("case/demo/data.conf"));
//	Log.info(readCase.PreContentList("case/demo/first.case", "case/demo/data.conf"));
		Log.info(readCase.ContentConvert("case/demo/init.case", "case/demo/data.conf"));


	}
	
	
}

